package com.archgeek.java.conc.synchro;

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;

import java.nio.ByteOrder;
import java.util.concurrent.TimeUnit;

/**
 * 各种锁的测试
 *
 * @author pizhihui
 * @date 2023-04-20 10:23
 */
public class SynchronizedUpgrade01 {

    public static void main(String[] args) throws InterruptedException {
        //查看字节序
        System.out.println(ByteOrder.nativeOrder());
        //打印当前jvm信息
        System.out.println("======================================");
        System.out.println(VM.current().details());

        // 00000001
        System.out.println("============================ 无锁 ====================");
        normalNoSyhnCode();

        // -XX:-UseBiasedLocking
        // 01000000
        System.out.println("============================ 轻量级锁 ====================");
        lightWeightLock();

        System.out.println("============================ 偏向锁 ======================");
        // 00000101
        biaseLock();

        System.out.println("============================ 重量级锁 =====================");
        // 00001010
        weightLock();

    }


    private static void normalNoSyhnCode() {
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        int i = o.hashCode();
        System.out.println("hashCode: " + Integer.toHexString(i));
        System.out.println(ClassLayout.parseInstance(o).toPrintable());

    }

    private static void biaseLock() throws InterruptedException {
        // 睡眠 4 秒
        TimeUnit.SECONDS.sleep(4);
        Object lock = new Object();
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        synchronized (lock) {
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    }

    private static void lightWeightLock() {
        Object o = new Object();
        synchronized (o) {
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }

    private static void weightLock() {
        Object o = new Object();
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                synchronized (o) {
                    System.out.println(ClassLayout.parseInstance(o).toPrintable());
                }
            }).start();
        }
    }

}

